#ifndef LASERNODE_H
#define LASERNODE_H

#include "behaviortree_cpp_v3/bt_factory.h"
#include <iostream>

using namespace BT;

namespace LaserNode
{
    BT::NodeStatus IsReceiveStartSignal();

    //距离检测节点
    class LaserSpaceJudg :public ConditionNode
    {
    public:
        LaserSpaceJudg(const std::string& name, const NodeConfiguration& config):ConditionNode(name,config){}
        ~LaserSpaceJudg()override = default;

        static PortsList providedPorts()
        {
          return {InputPort<int>("space")};
        }

    protected:
      virtual NodeStatus tick() override;
    };

    //轴移动节点
    class AxisMoveToNode : public AsyncActionNode
    {
    public:
      AxisMoveToNode(const std::string& name, const NodeConfiguration& config) :
        AsyncActionNode(name, config){}

      NodeStatus tick() override
      {
        std::string axisStr;
        int x = 0;
        int y = 0;
        int z = 0;

        if (getInput("axis", axisStr) && getInput("x", x) && getInput("y", y) && getInput("z", z))
        {
            std::cout << "axis: " << axisStr << " move to:" << "[" << x << "," << y << "," << z << "]" << std::endl;
            if(x < 0 || y < 0 || z < 0)
            {
                return NodeStatus::FAILURE;
            }

            std::this_thread::sleep_for(std::chrono::milliseconds(1000));
            return NodeStatus::SUCCESS;
        }
        else
        {
          return NodeStatus::FAILURE;
        }
      }

      static PortsList providedPorts()
      {
        return {InputPort<std::string>("axis"),InputPort<int>("x"),InputPort<int>("y"),InputPort<int>("z")};
      }
    };

    //报警节点
    class AlarmNode : public BT::SyncActionNode
    {
    public:
      AlarmNode(const std::string& name, const BT::NodeConfiguration& config) :
        BT::SyncActionNode(name, config)
      {}

      static PortsList providedPorts()
      {
        return {InputPort<std::string>("message"),InputPort<int>("type")};
      }

      BT::NodeStatus tick() override
      {
          int msgType = 0;
          std::string msg{};
          getInput("message",msg);
          getInput("type",msgType);

          if(msgType < 0)
          {
              std::cout << "alarm error:" << msg << std::endl;
          }
          else
          {
              std::cout << "alarm infor:" << msg << std::endl;
          }
          return NodeStatus::SUCCESS;
      }
    };

    //加工节点（异步节点）
    class ProcessNode : public AsyncActionNode
    {
    public:
      ProcessNode(const std::string& name, const NodeConfiguration& config) :
        AsyncActionNode(name, config)
      {}

      NodeStatus tick() override
      {
        std::string axisStr;
        int time = 0;

        if (getInput("axis", axisStr) && getInput("time", time))
        {
          std::this_thread::sleep_for(std::chrono::milliseconds(time));
          std::cout << "axis: " << axisStr << " work finish:" << time << std::endl;
          return NodeStatus::SUCCESS;
        }
        else
        {
          return NodeStatus::FAILURE;
        }
      }

      static PortsList providedPorts()
      {
        return {InputPort<std::string>("axis"),InputPort<int>("time")};
      }

    };

    void RegisterNodes(BT::BehaviorTreeFactory& factory);
}

#endif // LASERNODE_H
